Public Class SclCrawler
    Inherits WebCrawler

    Private Const IgnoreSpells As String = "Mark of the Fallen Champion@"

    Private Const HealRateFilterForCrawling As Single = 0.0 '[%] 
    Private Const DmgOutRateFilterForCrawling As Single = 0.0 '[%]
    Private Const DmgInRateFilterForCrawling As Single = 0.0 '[%]

    Private Const DataXmlPath As String = "/wws-history/data.xml"

    Public Sub New(ByRef AccessProgressNotify As WowCrawler.DataAccessProgressNotify)
        MyBase.new(AccessProgressNotify)
    End Sub

    Public Overrides Function Crawl(ByRef RaidInfo As RaidData, Optional ByVal IsFullUpdate As Boolean = True) As Boolean
        Dim NoError As Boolean = True


        If Mid(RaidInfo.BaseUrl, Len(RaidInfo.BaseUrl), 1) = "/" Then
            RaidInfo.BaseUrl = Mid(RaidInfo.BaseUrl, 1, Len(RaidInfo.BaseUrl) - 1)
        End If

        If CrawlDataXml(RaidInfo.BaseUrl, RaidInfo.Region, RaidInfo.Realm, RaidInfo.RaidName, RaidInfo.Type, IsFullUpdate) = False Then
            NoError = False
        End If

        If NoError Then
            If CrawlHtml(RaidInfo.BaseUrl, IsFullUpdate) = False Then
                ProgNotify.Notify("Error: CrawlHtml(" & RaidInfo.BaseUrl & ")")
                NoError = False
            End If
        End If

        ProgNotify.Notify("Crawl - Guess Char Build")
        Dim i As Integer
        For i = 0 To Raids.Length - 1
            GuessCharaBuild(Raids(i), IsFullUpdate)
        Next

        ProgNotify.Notify("Crawl - Estimation and Feedback")
        If NoError Then

            PwsEstimation(RaidInfo)

            If InStr(LCase(RaidInfo.BaseUrl), "http://") = 1 Then
            Else
                FeedbackEstimation(RaidInfo)
            End If
        End If

        ProgNotify.Notify("Crawl - Done")
        Return True
    End Function

#Region "data.xml"
    Private Function CrawlDataXml(ByVal BaseURL As String, ByVal Region As String, ByVal Realm As String, ByVal RaidName As String, ByVal SType As RaidData.StatType, ByVal isFullUpdate As Boolean) As Boolean
        ProgNotify.Notify("CrawlDataXml(" & BaseURL & ")")

        Dim XmlData As New Xml.XmlDocument
        Try
            XmlData.Load(BaseURL & DataXmlPath)
        Catch ex As Exception
            ProgNotify.Notify("Error: CrawlDataXml.XmlLoad - " & BaseURL & DataXmlPath)
            Return False
        End Try

        Dim RaidIdx As Integer = -1
        If Raids Is Nothing Then
            ReDim Raids(0)
            Raids(0) = New RaidData
            RaidIdx = 0

            Raids(RaidIdx).LastUpdate = Now - (CDate("2000/1/1") - CDate("1900/1/1"))
            Raids(RaidIdx).BaseUrl = BaseURL
        Else
            Dim i As Integer

            For i = 0 To Raids.Length - 1
                If LCase(Raids(i).BaseUrl) = LCase(BaseURL) Then
                    RaidIdx = i
                    Exit For
                ElseIf Raids(i).BaseUrl = "" Then
                    Raids(i).BaseUrl = BaseURL
                    RaidIdx = i
                    Exit For
                End If
            Next

            If RaidIdx < 0 Then
                RaidIdx = Raids.Length
                ReDim Preserve Raids(RaidIdx)
                Raids(RaidIdx) = New RaidData

                Raids(RaidIdx).LastUpdate = Now - (CDate("2000/1/1") - CDate("1900/1/1"))
                Raids(RaidIdx).BaseUrl = BaseURL
            End If
        End If

        Raids(RaidIdx).Type = SType
        Raids(RaidIdx).Region = Region
        Raids(RaidIdx).Realm = Realm
        Raids(RaidIdx).RaidName = RaidName

        ParseDataXml(Raids(RaidIdx), XmlData)

        Return True
    End Function

    Private Function ParseDataXml(ByRef Raids As RaidData, ByRef XmlData As Xml.XmlDocument) As Boolean
        Dim RaidNode As Xml.XmlElement

        For Each RaidNode In XmlData.SelectNodes("wws-history/raid")
            Dim Created As Boolean = False

            Dim BossIdx As Long = -1
            If Raids.Bosses Is Nothing Then
                ReDim Raids.Bosses(0)
                Created = True
                Raids.Bosses(0) = New BossData
                BossIdx = 0
            Else
                Dim i As Long
                For i = 0 To Raids.Bosses.Length - 1
                    If LCase(Raids.Bosses(i).Dir) = LCase(RaidNode.Attributes("dir").Value) Then
                        BossIdx = i
                        Created = False
                        Exit For
                    End If
                Next

                If BossIdx < 0 Then
                    BossIdx = Raids.Bosses.Length
                    ReDim Preserve Raids.Bosses(BossIdx)
                    Created = True
                    Raids.Bosses(BossIdx) = New BossData
                End If
            End If

            If Created Then
                Raids.Bosses(BossIdx).Dir = RaidNode.Attributes("dir").Value

                Raids.Bosses(BossIdx).RaidDmgIn = 0
                Raids.Bosses(BossIdx).RaidHeal = 0
                Raids.Bosses(BossIdx).RaidEffHeal = 0

                Raids.Bosses(BossIdx).Attempt = 0
                Raids.Bosses(BossIdx).Killed = 0
            End If

            Raids.Bosses(BossIdx).Attempt = 1

            Dim boss As String = RaidNode.Attributes("comment").Value
            If InStr(LCase(boss), " try ") > 0 Then
                Raids.Bosses(BossIdx).Killed = 0
                Raids.Bosses(BossIdx).Boss = Left(boss, InStr(LCase(boss), " try ") - 1)
            Else
                Raids.Bosses(BossIdx).Killed = 1
                Raids.Bosses(BossIdx).Boss = boss
            End If


            Raids.Bosses(BossIdx).RaidDate = CalculateDate(RaidNode.Attributes("start").Value)
            Raids.Bosses(BossIdx).Area = RaidNode.Attributes("zone").Value
            Raids.Bosses(BossIdx).Duration = Math.Round(RaidNode.Attributes("lg").Value / (60 * 1000), 2)
            Raids.Bosses(BossIdx).RaidDmgOut = RaidNode.Attributes("dmg").Value

            Try
                If RaidNode.Attributes("heroic").Value = "0" Then
                    Raids.Bosses(BossIdx).Heroic = BossData.HeroicType.Normal
                Else
                    Raids.Bosses(BossIdx).Heroic = BossData.HeroicType.Heroic
                End If
            Catch ex As Exception
                Raids.Bosses(BossIdx).Heroic = BossData.HeroicType.Unknown
            End Try

            ProgNotify.Notify("ParseDataXml(" & BossIdx + 1 & " - " & Raids.Bosses(BossIdx).Boss & ")")

            Dim CharaNode As Xml.XmlElement
            For Each CharaNode In RaidNode.SelectNodes("player")
                Dim ChCreated As Boolean = False

                Dim CharaIdx As Integer = -1
                If Raids.Bosses(BossIdx).Characters Is Nothing Then
                    ReDim Raids.Bosses(BossIdx).Characters(0)
                    ChCreated = True
                    Raids.Bosses(BossIdx).Characters(0) = New CharaData
                    CharaIdx = 0
                Else
                    Dim i As Long
                    For i = 0 To Raids.Bosses(BossIdx).Characters.Length - 1
                        If LCase(Raids.Bosses(BossIdx).Characters(i).CharaName) = LCase(CharaNode.Attributes("name").Value) Then
                            CharaIdx = i
                            ChCreated = False
                            Exit For
                        End If
                    Next

                    If CharaIdx < 0 Then
                        CharaIdx = Raids.Bosses(BossIdx).Characters.Length
                        ReDim Preserve Raids.Bosses(BossIdx).Characters(CharaIdx)
                        ChCreated = True
                        Raids.Bosses(BossIdx).Characters(CharaIdx) = New CharaData
                    End If
                End If

                If ChCreated Then
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaName = CharaNode.Attributes("name").Value

                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaID = ""
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaPres = 0
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaAct = 0

                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaDmgOut = 0
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaDmgIn = 0
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaEffHeal = 0
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaHeal = 0

                    Try
                        Raids.Bosses(BossIdx).Characters(CharaIdx).CharaClass = CharaNode.Attributes("clsname").Value
                    Catch ex As Exception
                        Raids.Bosses(BossIdx).Characters(CharaIdx).CharaClass = GetClassName(CharaNode.Attributes("classe").Value)
                    End Try
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaBuild = ""

                    Try
                        Raids.Bosses(BossIdx).Characters(CharaIdx).DmgOutRate = CharaNode.Attributes("dmgout").Value
                    Catch ex As Exception
                        Raids.Bosses(BossIdx).Characters(CharaIdx).DmgOutRate = 0
                    End Try
                    Try
                        Raids.Bosses(BossIdx).Characters(CharaIdx).DmgInRate = CharaNode.Attributes("dmgin").Value
                    Catch ex As Exception
                        Raids.Bosses(BossIdx).Characters(CharaIdx).DmgInRate = 0
                    End Try
                    Try
                        Raids.Bosses(BossIdx).Characters(CharaIdx).EffHealRate = CharaNode.Attributes("heal").Value
                    Catch ex As Exception
                        Raids.Bosses(BossIdx).Characters(CharaIdx).EffHealRate = 0
                    End Try
                    Try
                        Raids.Bosses(BossIdx).Characters(CharaIdx).OverHeal = CharaNode.Attributes("ovh").Value
                    Catch ex As Exception
                        Raids.Bosses(BossIdx).Characters(CharaIdx).OverHeal = 0
                    End Try

                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaDispel = CharaNode.Attributes("decurse").Value
                    Raids.Bosses(BossIdx).Characters(CharaIdx).CharaDeath = CharaNode.Attributes("death").Value
                End If
            Next
        Next

        Return True
    End Function

    Private Function GetClassName(ByVal classe As String) As String
        Dim acn As String = classe

        Select Case classe
            Case "pri"
                acn = "Priest"
            Case "pal"
                acn = "Paladin"
            Case "drd"
                acn = "Druid"
            Case "sha"
                acn = "Shaman"
            Case "wrl"
                acn = "Warlock"
            Case "mag"
                acn = "Mage"
            Case "hnt"
                acn = "Hunter"
            Case "war"
                acn = "Warrior"
            Case "rog"
                acn = "Rogue"
            Case Else
                acn = classe
        End Select

        GetClassName = acn
    End Function

    Private Function CalculateDate(ByVal DateValue As Long) As Date
        Dim CalDate As Date = "1970/1/1 00:00:00.000"

        CalDate = CalDate.AddTicks(DateValue * 10000)
        CalDate = CalDate.ToLocalTime

        '        CalDate = CalDate.AddHours(-4.5)

        Return CalDate
    End Function

#End Region

#Region "Raid HTML"
    Public Function CrawlHtml(ByVal BaseURL As String, ByVal IsFullUpdate As Boolean) As Boolean
        Dim r As Integer
        For r = 0 To Raids.Length - 1
            If Raids(r).BaseUrl = BaseURL Then
                Dim b As Integer
                Dim c As Integer

                For b = 0 To Raids(r).Bosses.Length - 1
                    If CrawlHtmlRaid(BaseURL, Raids(r).Bosses(b)) = False Then
                        ProgNotify.Notify("Error: CrawlHtmlRaid - " & Raids(r).Bosses(b).Dir)
                        'return false
                    Else
                        For c = 0 To Raids(r).Bosses(b).Characters.Length - 1
                            If Raids(r).Bosses(b).Characters(c).EffHealRate >= HealRateFilterForCrawling _
                                            Or Raids(r).Bosses(b).Characters(c).DmgOutRate >= DmgOutRateFilterForCrawling _
                                            Or Raids(r).Bosses(b).Characters(c).DmgInRate >= DmgInRateFilterForCrawling Then
                                If CrawlHtmlChara(BaseURL & "/" & Raids(r).Bosses(b).Dir, Raids(r).Bosses(b).Characters(c), IsFullUpdate) = False Then
                                    'MsgBox("Error: CrawlHtmlChara - " & Raids(r).Bosses(b).Characters(c).CharaID)
                                    'Return False
                                End If
                            End If
                        Next
                    End If
                Next
            End If

            Raids(r).LastUpdate = Now
            'Export()
        Next
        Return True
    End Function

    Private Function CrawlHtmlChara(ByVal Url As String, ByRef Charas As CharaData, ByVal IsFullUpdate As Boolean) As Boolean
        Dim RetCode As Boolean = True

        If IsFullUpdate Or Not ((Charas.Heals IsNot Nothing) Or (Charas.DamageIn IsNot Nothing) Or (Charas.DamageOut IsNot Nothing)) Then

            'ProgNotify.Notify("CrawlHtmlChara(" & Charas.CharaName & "/" & Charas.CharaClass & ")")
            Dim DHtmlDoc As New Xml.XmlDocument
            Try
                Dim dhtml As String = GetDHtml(Url & "/actor_" & Charas.CharaID & ".html")
                dhtml = Replace(dhtml, "&ndash;", "-")
                DHtmlDoc.LoadXml(dhtml)
            Catch ex As Exception
                RetCode = False
            End Try

            If RetCode = True Then
                If IsFullUpdate Then
                    Charas.Heals = Nothing
                    Charas.DamageIn = Nothing
                    Charas.DamageOut = Nothing
                End If

                Try
                    DHtmlDoc.Save(My.Computer.FileSystem.CombinePath(My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData, "LastCharaData.html"))
                Catch ex As Exception
                End Try

                Dim HealNode As Xml.XmlNode = GetAttributeNode(DHtmlDoc.LastChild, "id", "tab_healing")
                Dim DmgOutNode As Xml.XmlNode = GetAttributeNode(DHtmlDoc.LastChild, "id", "tab_damage")
                Dim CastsNode As Xml.XmlNode = GetAttributeNode(DHtmlDoc.LastChild, "id", "tab_casts_and_power")

                If CrawlHtmlCharaHeal(HealNode, Charas) = False Then RetCode = False
                If CrawlHtmlCharaCast(CastsNode, Charas) = False Then RetCode = False
                If CrawlHtmlCharaDmgOut(DmgOutNode, Charas) = False Then RetCode = False
            End If
        End If

        Return RetCode
    End Function

    Private Function CrawlHtmlCharaHeal(ByRef HealNode As Xml.XmlNode, ByRef Charas As CharaData) As Boolean
        If HealNode IsNot Nothing And Charas.EffHealRate >= HealRateFilterForCrawling Then
            Dim InArea As Boolean = False

            Dim c2 As Xml.XmlNode
            Dim c3 As Xml.XmlNode
            Dim c4 As Xml.XmlNode
            Dim c5 As Xml.XmlNode

            For Each c2 In HealNode.ChildNodes
                If c2.Name = "table" Then
                    For Each c3 In c2.ChildNodes
                        If c3.Name = "tr" Then
                            Dim trCls As String = ""
                            Try
                                trCls = c3.Attributes("class").Value
                            Catch ex As Exception
                                trCls = ""
                            End Try

                            For Each c4 In c3.ChildNodes
                                If c4.Name = "th" Then
                                    Dim name As String = ""

                                    Dim thCls As String = ""
                                    Try
                                        thCls = c4.Attributes("class").Value
                                    Catch ex As Exception
                                        thCls = ""
                                    End Try

                                    If InStr(thCls, "title") = 1 Then
                                        For Each c5 In c4.ChildNodes
                                            If c5.Name = "a" Then
                                                name = c5.InnerText

                                                If name = "Healing Out by Ability" Then
                                                    InArea = True
                                                Else
                                                    InArea = False
                                                End If

                                                Exit For
                                            End If
                                        Next
                                    End If

                                ElseIf c4.Name = "td" And InArea Then
                                    If InStr(trCls, "sectionMaster") = 1 Then
                                        Dim HD As New HealData
                                        Dim name As String
                                        name = Replace(c4.InnerText, "(+) ", "")

                                        Dim idx As Integer = -1
                                        If Charas.Heals Is Nothing Then
                                            idx = 0
                                            ReDim Charas.Heals(idx)
                                            Charas.Heals(idx) = New HealData
                                        Else
                                            Dim i As Integer
                                            For i = 0 To Charas.Heals.Length - 1
                                                If Charas.Heals(i).SpellName = name And name <> "Beacon of Light" Then
                                                    idx = i
                                                    Exit For
                                                End If
                                            Next
                                            If idx < 0 Then
                                                idx = Charas.Heals.Length
                                                ReDim Preserve Charas.Heals(idx)
                                                Charas.Heals(idx) = New HealData
                                            End If
                                        End If
                                        HD = Charas.Heals(idx)

                                        HD.SpellName = name
                                        Dim chn As Xml.XmlElement = c4  ' spell

                                        chn = chn.NextSibling   ' eff heal
                                        If chn.InnerText = "" Then
                                            HD.EffHeal = 0
                                        Else
                                            HD.EffHeal = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' %
                                        If chn.InnerText = "" Then
                                            HD.EffHealRate = 0
                                        Else
                                            HD.EffHealRate = Replace(chn.InnerText, "%", "")
                                        End If

                                        chn = chn.NextSibling   ' hits
                                        If chn.InnerText = "" Then
                                            HD.Hits = 0
                                        Else
                                            HD.Hits = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ticks
                                        If chn.InnerText = "" Then
                                            HD.Ticks = 0
                                        Else
                                            HD.Ticks = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ave hit
                                        If chn.InnerText = "" Then
                                            HD.AveHit = 0
                                        Else
                                            HD.AveHit = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ave crit
                                        If chn.InnerText = "" Then
                                            HD.AveCrit = 0
                                        Else
                                            HD.AveCrit = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ave tick
                                        If chn.InnerText = "" Then
                                            HD.AveTick = 0
                                        Else
                                            HD.AveTick = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' % crit
                                        If chn.InnerText = "" Then
                                            HD.Crits = 0
                                        Else
                                            HD.Crits = Math.Round(HD.Hits * Replace(chn.InnerText, "%", "") / 100, 0)
                                            If HD.AveCrit > 0 And HD.Crits = 0 Then
                                                HD.Crits = 1
                                            End If
                                        End If

                                        chn = chn.NextSibling   ' % over heal
                                        If chn.InnerText = "" Then
                                            HD.Heal = HD.EffHeal
                                        Else
                                            Dim oh As Single = Replace(chn.InnerText, "%", "") / 100
                                            If oh <= 0 Then
                                                HD.Heal = HD.EffHeal
                                            ElseIf 1 <= oh Then
                                                HD.Heal = HD.AveHit * (HD.Hits - HD.Crits) + HD.AveCrit * HD.Crits + HD.AveTick * HD.Ticks
                                            Else
                                                HD.Heal = HD.EffHeal / (1 - oh)
                                            End If
                                        End If

                                    End If

                                    Exit For
                                End If
                            Next
                        End If
                    Next
                End If
            Next
        End If
        Return True
    End Function

    Private Function CrawlHtmlCharaDmgOut(ByRef DmgOutNode As Xml.XmlNode, ByRef Charas As CharaData) As Boolean
        If DmgOutNode IsNot Nothing And Charas.DmgOutRate >= DmgOutRateFilterForCrawling Then
            Dim InArea As Boolean = False

            Dim c2 As Xml.XmlNode
            Dim c3 As Xml.XmlNode
            Dim c4 As Xml.XmlNode
            Dim c5 As Xml.XmlNode

            For Each c2 In DmgOutNode.ChildNodes
                If c2.Name = "table" Then
                    Dim IsDmgOut As Boolean = False
                    Dim spellname As String = ""
                    Dim target As String = ""

                    For Each c3 In c2.ChildNodes
                        If c3.Name = "tr" Then

                            Dim trCls As String = ""
                            Try
                                trCls = c3.Attributes("class").Value
                            Catch ex As Exception
                                trCls = ""
                            End Try

                            For Each c4 In c3.ChildNodes

                                If c4.Name = "th" Then
                                    Dim name As String = ""
                                    Dim thCls As String = ""
                                    Try
                                        thCls = c4.Attributes("class").Value
                                    Catch ex As Exception
                                        thCls = ""
                                    End Try

                                    If InStr(thCls, "title") = 1 Then
                                        For Each c5 In c4.ChildNodes
                                            If c5.Name = "a" Then
                                                name = c5.InnerText

                                                If name = "Damage Out by Ability" Then
                                                    IsDmgOut = True
                                                    InArea = True
                                                ElseIf name = "Damage In by Source" Then
                                                    IsDmgOut = False
                                                    InArea = True
                                                Else
                                                    InArea = False
                                                End If

                                                Exit For
                                            End If
                                        Next
                                    End If
                                    Exit For

                                ElseIf c4.Name = "td" And InArea Then
                                    Dim DpsD As New DpsData

                                    If InStr(trCls, "sectionMaster") = 1 Then
                                        If IsDmgOut Then
                                            spellname = Replace(c4.InnerText, "(+) ", "")
                                            target = ""
                                        Else
                                            target = Replace(c4.InnerText, "(+) ", "")
                                            spellname = ""
                                        End If

                                    Else
                                        Dim idx As Integer = -1
                                        If IsDmgOut Then
                                            target = c4.InnerText

                                            If Charas.DamageOut Is Nothing Then
                                                idx = 0
                                                ReDim Charas.DamageOut(idx)
                                                Charas.DamageOut(idx) = New DpsData
                                            Else
                                                Dim i As Integer
                                                For i = 0 To Charas.DamageOut.Length - 1
                                                    If Charas.DamageOut(i).SpellName = spellname And Charas.DamageOut(i).Target = target Then
                                                        idx = i
                                                        Exit For
                                                    End If
                                                Next
                                                If idx < 0 Then
                                                    idx = Charas.DamageOut.Length
                                                    ReDim Preserve Charas.DamageOut(idx)
                                                    Charas.DamageOut(idx) = New DpsData
                                                End If
                                            End If

                                            DpsD = Charas.DamageOut(idx)
                                        Else
                                            spellname = c4.InnerText

                                            If Charas.DamageIn Is Nothing Then
                                                idx = 0
                                                ReDim Charas.DamageIn(idx)
                                                Charas.DamageIn(idx) = New DpsData
                                            Else
                                                Dim i As Integer
                                                For i = 0 To Charas.DamageIn.Length - 1
                                                    If Charas.DamageIn(i).SpellName = spellname And Charas.DamageIn(i).Target = target Then
                                                        idx = i
                                                        Exit For
                                                    End If
                                                Next
                                                If idx < 0 Then
                                                    idx = Charas.DamageIn.Length
                                                    ReDim Preserve Charas.DamageIn(idx)
                                                    Charas.DamageIn(idx) = New DpsData
                                                End If
                                            End If

                                            DpsD = Charas.DamageIn(idx)
                                        End If

                                        DpsD.SpellName = spellname
                                        DpsD.Target = target

                                        Dim chn As Xml.XmlElement = c4  ' spell or target

                                        chn = chn.NextSibling   ' total damage
                                        If chn.InnerText = "" Then
                                            DpsD.Damage = 0
                                        Else
                                            DpsD.Damage = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' %
                                        If chn.InnerText = "" Then
                                            DpsD.DamageRate = 0
                                        Else
                                            DpsD.DamageRate = Replace(chn.InnerText, "%", "")
                                        End If

                                        chn = chn.NextSibling   ' dps
                                        chn = chn.NextSibling   ' time

                                        chn = chn.NextSibling   ' hits
                                        If chn.InnerText = "" Then
                                            DpsD.Hits = 0
                                        Else
                                            DpsD.Hits = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ticks
                                        If chn.InnerText = "" Then
                                            DpsD.Ticks = 0
                                        Else
                                            DpsD.Ticks = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ave hit
                                        If chn.InnerText = "" Then
                                            DpsD.AveHit = 0
                                        Else
                                            DpsD.AveHit = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ave crit
                                        If chn.InnerText = "" Then
                                            DpsD.AveCrit = 0
                                        Else
                                            DpsD.AveCrit = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' ave tick
                                        If chn.InnerText = "" Then
                                            DpsD.AveTick = 0
                                        Else
                                            DpsD.AveTick = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' % crit
                                        If chn.InnerText = "" Then
                                            DpsD.Crits = 0
                                        Else
                                            DpsD.Crits = Math.Round(DpsD.Hits * Replace(chn.InnerText, "%", "") / 100, 0)
                                            If DpsD.AveCrit > 0 And DpsD.Crits = 0 Then
                                                DpsD.Crits = 1
                                            End If
                                        End If

                                        chn = chn.NextSibling   ' avoid
                                        If chn.InnerText = "" Then
                                            DpsD.Avoid = 0
                                        Else
                                            DpsD.Avoid = Replace(chn.InnerText, "%", "")
                                        End If
                                    End If
                                    Exit For
                                End If
                            Next
                        End If
                    Next
                End If
            Next
        End If

        Return True
    End Function

    Enum AreaCode
        NotInArea
        Casts
        PowerGains
        AuraGained
    End Enum

    Private Function CrawlHtmlCharaCast(ByRef CastsNode As Xml.XmlNode, ByRef Charas As CharaData) As Boolean

        Dim PWScasts As Boolean = False

        If CastsNode IsNot Nothing Then
            Dim InArea As AreaCode = AreaCode.NotInArea

            Dim c2 As Xml.XmlNode
            Dim c3 As Xml.XmlNode
            Dim c4 As Xml.XmlNode
            Dim c5 As Xml.XmlNode

            For Each c2 In CastsNode.ChildNodes
                If c2.Name = "table" Then
                    For Each c3 In c2.ChildNodes
                        If c3.Name = "tr" Then
                            Dim trCls As String = ""
                            Try
                                trCls = c3.Attributes("class").Value
                            Catch ex As Exception
                                trCls = ""
                            End Try

                            For Each c4 In c3.ChildNodes
                                If c4.Name = "th" Then
                                    Dim name As String = ""

                                    Dim thCls As String = ""
                                    Try
                                        thCls = c4.Attributes("class").Value
                                    Catch ex As Exception
                                        thCls = ""
                                    End Try

                                    If InStr(thCls, "title") = 1 Then
                                        For Each c5 In c4.ChildNodes
                                            If c5.Name = "a" Then
                                                name = c5.InnerText

                                                If name = "Casts" Then
                                                    InArea = AreaCode.Casts
                                                ElseIf name = "Power Gains" Then
                                                    InArea = AreaCode.PowerGains
                                                ElseIf name = "Aura Gained" Then
                                                    InArea = AreaCode.AuraGained
                                                Else
                                                    InArea = AreaCode.NotInArea
                                                End If

                                                Exit For
                                            End If
                                        Next
                                    End If

                                ElseIf c4.Name = "td" And InArea = AreaCode.Casts Then

                                    '------------- CASTS

                                    If InStr(trCls, "sectionMaster") = 1 Then
                                        Dim HD As New HealData
                                        Dim name As String
                                        name = Replace(c4.InnerText, "(+) ", "")

                                        Dim idx As Integer = -1

                                        If InStr(name, "Power Word: Shield") = 1 Or InStr(name, "Sacred Shield") = 1 Or InStr(name, "Divine Aegis") = 1 Then

                                            If Charas.Heals Is Nothing Then
                                                idx = -1
                                            Else
                                                Dim i As Integer
                                                For i = 0 To Charas.Heals.Length - 1
                                                    If Charas.Heals(i).SpellName = name Then
                                                        idx = i
                                                        Exit For
                                                    ElseIf InStr(name, Charas.Heals(i).SpellName) = 1 Then  ' AaaBbb (rXX) == AaaBbb
                                                        If Mid(name, Charas.Heals(i).SpellName.Length + 1, 2) = " (" Then
                                                            idx = i
                                                            Exit For
                                                        End If
                                                    ElseIf InStr(Charas.Heals(i).SpellName, name) = 1 Then
                                                        If Mid(Charas.Heals(i).SpellName, name.Length + 1, 2) = " (" Then
                                                            idx = i
                                                            Exit For
                                                        End If
                                                    End If
                                                Next
                                            End If


                                            If InStr(name, "Power Word: Shield") = 1 Then
                                                PWScasts = True
                                            End If

                                            If idx < 0 Then
                                                If Charas.Heals Is Nothing Then
                                                    idx = 0
                                                Else
                                                    idx = Charas.Heals.Length
                                                End If

                                                ReDim Preserve Charas.Heals(idx)
                                                Charas.Heals(idx) = New HealData
                                                Charas.Heals(idx).SpellName = name
                                            End If

                                            HD = Charas.Heals(idx)

                                            Dim chn As Xml.XmlElement = c4  ' spell
                                            chn = chn.NextSibling   ' targets
                                            chn = chn.NextSibling   ' casts
                                            If chn.InnerText = "" Then
                                                HD.Casts = 0
                                            Else
                                                HD.Casts = Replace(chn.InnerText, ",", "")
                                            End If

                                            chn = chn.NextSibling   ' ticks
                                        End If
                                    End If
                                ElseIf c4.Name = "td" And InArea = AreaCode.PowerGains Then

                                    '------------- Power Gains

                                    If InStr(trCls, "sectionMaster") = 1 Then
                                        Dim HD As New HealData
                                        Dim name As String
                                        name = Replace(c4.InnerText, "(+) ", "")

                                        Dim idx As Integer = -1

                                        If InStr(name, "Rapture (mana)") = 1 And PWScasts Then

                                            If Charas.Heals Is Nothing Then
                                                idx = -1
                                            Else
                                                Dim i As Integer
                                                For i = 0 To Charas.Heals.Length - 1
                                                    If Charas.Heals(i).SpellName = name Then
                                                        idx = i
                                                        Exit For
                                                    ElseIf InStr(name, Charas.Heals(i).SpellName) = 1 Then  ' AaaBbb (rXX) == AaaBbb
                                                        If Mid(name, Charas.Heals(i).SpellName.Length + 1, 2) = " (" Then
                                                            idx = i
                                                            Exit For
                                                        End If
                                                    ElseIf InStr(Charas.Heals(i).SpellName, name) = 1 Then
                                                        If Mid(Charas.Heals(i).SpellName, name.Length + 1, 2) = " (" Then
                                                            idx = i
                                                            Exit For
                                                        End If
                                                    End If
                                                Next
                                            End If

                                            If idx < 0 Then
                                                If Charas.Heals Is Nothing Then
                                                    idx = 0
                                                Else
                                                    idx = Charas.Heals.Length
                                                End If

                                                ReDim Preserve Charas.Heals(idx)
                                                Charas.Heals(idx) = New HealData
                                                Charas.Heals(idx).SpellName = name

                                            End If

                                            HD = Charas.Heals(idx)
                                            Dim rapture As Integer = 0

                                            Dim chn As Xml.XmlElement = c4  ' spell
                                            chn = chn.NextSibling   ' source
                                            chn = chn.NextSibling   ' gained
                                            chn = chn.NextSibling   ' ticks
                                            If chn.InnerText = "" Then
                                                rapture = 0
                                            Else
                                                rapture = Replace(chn.InnerText, ",", "")
                                            End If
                                            If HD.Casts <= rapture Then
                                                HD.Casts = rapture
                                            End If

                                            chn = chn.NextSibling   ' ticks
                                        End If
                                    End If
                                End If
                                Exit For
                            Next
                        End If
                    Next
                End If
            Next
        End If

        Return True
    End Function

    Private Function CrawlHtmlRaid(ByVal BaseUrl As String, ByRef Bosses As BossData) As Boolean
        ProgNotify.Notify("CrawlHtmlRaid(" & Format(Bosses.RaidDate, "MM-dd-yyyy") & " " & Bosses.Boss & ")")

        Dim DHtmlDoc As New Xml.XmlDocument
        Try
            Dim dhtml As String = GetDHtml(BaseUrl & "/" & Bosses.Dir & "/index.html")
            DHtmlDoc.LoadXml(dhtml)
        Catch ex As Exception
            Return False
        End Try
        Try
            DHtmlDoc.Save(My.Computer.FileSystem.CombinePath(My.Computer.FileSystem.SpecialDirectories.AllUsersApplicationData, "LastBossData.html"))
        Catch ex As Exception
        End Try

        '--- omg! xpath does not work ,,,

        Dim HealNode As Xml.XmlNode = GetAttributeNode(DHtmlDoc.LastChild, "id", "tab_healing")
        Dim DmgOutNode As Xml.XmlNode = GetAttributeNode(DHtmlDoc.LastChild, "id", "tab_damage_out")
        Dim DmgInNode As Xml.XmlNode = GetAttributeNode(DHtmlDoc.LastChild, "id", "tab_damage_in")

        Dim c2 As Xml.XmlNode
        Dim c3 As Xml.XmlNode
        Dim c4 As Xml.XmlNode
        Dim c5 As Xml.XmlNode

        '--- get characters Heal data
        For Each c2 In HealNode.ChildNodes
            If c2.Name = "table" Then
                For Each c3 In c2.ChildNodes
                    If c3.Name = "tr" Then
                        For Each c4 In c3.ChildNodes
                            If c4.Name = "td" Then
                                Dim name As String = ""
                                For Each c5 In c4.ChildNodes
                                    If c5.Name = "a" Then
                                        name = c5.InnerText
                                        Exit For
                                    End If
                                Next

                                Dim ch As Integer
                                Dim chn As Xml.XmlElement = c4
                                For ch = 0 To Bosses.Characters.Length - 1
                                    If Bosses.Characters(ch).CharaName = name Then

                                        chn = chn.NextSibling   ' pres 00:00
                                        Bosses.Characters(ch).CharaPres = Mid(chn.InnerText, 1, 2) * 60 + Mid(chn.InnerText, 4, 2)

                                        chn = chn.NextSibling   ' -emp
                                        chn = chn.NextSibling   ' oh %
                                        If chn.InnerText = "" Then
                                            Bosses.Characters(ch).OverHeal = 0
                                        Else
                                            Bosses.Characters(ch).OverHeal = Mid(chn.InnerText, 1, Len(chn.InnerText) - 1)
                                        End If

                                        chn = chn.NextSibling   ' -emp
                                        chn = chn.NextSibling   ' eff heal ###,##0
                                        If chn.InnerText = "" Then
                                            Bosses.Characters(ch).CharaEffHeal = 0
                                        Else
                                            Bosses.Characters(ch).CharaEffHeal = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' eff heal rate %

                                        '--- calculate total heal
                                        If Bosses.Characters(ch).OverHeal < 100 Then
                                            Bosses.Characters(ch).CharaHeal = Bosses.Characters(ch).CharaEffHeal * 100 / (100 - Bosses.Characters(ch).OverHeal)
                                        Else
                                            Bosses.Characters(ch).CharaHeal = 0
                                        End If

                                        Exit For
                                    End If
                                Next

                            End If
                        Next
                    End If
                Next
            End If
        Next

        '--- get characters DmgOut data
        For Each c2 In DmgOutNode.ChildNodes
            If c2.Name = "table" Then
                For Each c3 In c2.ChildNodes
                    If c3.Name = "tr" Then
                        For Each c4 In c3.ChildNodes
                            If c4.Name = "td" Then
                                Dim name As String = ""
                                Dim ID As String = ""
                                For Each c5 In c4.ChildNodes
                                    If c5.Name = "a" Then
                                        name = c5.InnerText
                                        ID = c5.Attributes("href").Value

                                        ID = Replace(ID, "actor_", "")
                                        ID = Replace(ID, ".html", "")

                                        Exit For
                                    End If
                                Next

                                Dim ch As Integer
                                Dim chn As Xml.XmlElement = c4
                                For ch = 0 To Bosses.Characters.Length - 1
                                    If Bosses.Characters(ch).CharaName = name Then
                                        Bosses.Characters(ch).CharaID = ID

                                        chn = chn.NextSibling   ' pres 00:00
                                        chn = chn.NextSibling   ' act #0.0%
                                        If chn.InnerText = "" Then
                                            Bosses.Characters(ch).CharaAct = 0
                                        Else
                                            Bosses.Characters(ch).CharaAct = Math.Round(Bosses.Characters(ch).CharaPres * (CDbl(Replace(chn.InnerText, "%", "")) + 0.4) / 100, 0)
                                        End If

                                        chn = chn.NextSibling   ' pres Dps #,##0
                                        chn = chn.NextSibling   ' act Dps #,##0

                                        chn = chn.NextSibling   ' dmg out ###,##0
                                        If chn.InnerText = "" Then
                                            Bosses.Characters(ch).CharaDmgOut = 0
                                        Else
                                            Bosses.Characters(ch).CharaDmgOut = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' dmg out %

                                        Exit For
                                    End If
                                Next

                            End If
                        Next
                    End If
                Next
            End If
        Next


        '--- get characters DmgIn data
        For Each c2 In DmgInNode.ChildNodes
            If c2.Name = "table" Then
                For Each c3 In c2.ChildNodes
                    If c3.Name = "tr" Then
                        For Each c4 In c3.ChildNodes
                            If c4.Name = "td" Then
                                Dim name As String = ""
                                For Each c5 In c4.ChildNodes
                                    If c5.Name = "a" Then
                                        name = c5.InnerText
                                        Exit For
                                    End If
                                Next

                                Dim ch As Integer
                                Dim chn As Xml.XmlElement = c4
                                For ch = 0 To Bosses.Characters.Length - 1
                                    If Bosses.Characters(ch).CharaName = name Then
                                        chn = chn.NextSibling   ' pres 00:00
                                        chn = chn.NextSibling
                                        chn = chn.NextSibling   ' death
                                        chn = chn.NextSibling
                                        chn = chn.NextSibling   ' dmg in ###,##0
                                        If chn.InnerText = "" Then
                                            Bosses.Characters(ch).CharaDmgIn = 0
                                        Else
                                            Bosses.Characters(ch).CharaDmgIn = Replace(chn.InnerText, ",", "")
                                        End If

                                        chn = chn.NextSibling   ' dmg in %

                                        Exit For
                                    End If
                                Next

                            End If
                        Next
                    End If
                Next
            End If
        Next

        '--- sum for raid values
        Dim c As Integer
        Bosses.RaidHeal = 0
        Bosses.RaidEffHeal = 0
        Bosses.RaidDmgOut = 0
        Bosses.RaidDmgIn = 0
        Bosses.RaidDispel = 0
        Bosses.RaidDeath = 0
        For c = 0 To Bosses.Characters.Length - 1
            Bosses.RaidHeal += Bosses.Characters(c).CharaHeal
            Bosses.RaidEffHeal += Bosses.Characters(c).CharaEffHeal
            Bosses.RaidDmgOut += Bosses.Characters(c).CharaDmgOut
            Bosses.RaidDmgIn += Bosses.Characters(c).CharaDmgIn
            Bosses.RaidDispel += Bosses.Characters(c).CharaDispel
            Bosses.RaidDeath += Bosses.Characters(c).CharaDeath
        Next

        For c = 0 To Bosses.Characters.Length - 1
            Try
                Bosses.Characters(c).EffHealRate = Math.Round(Bosses.Characters(c).CharaEffHeal / Bosses.RaidEffHeal * 100, 2)
            Catch ex As Exception
                Bosses.Characters(c).EffHealRate = 0
            End Try
            Try
                Bosses.Characters(c).DmgOutRate = Math.Round(Bosses.Characters(c).CharaDmgOut / Bosses.RaidDmgOut * 100, 2)
            Catch ex As Exception
                Bosses.Characters(c).DmgOutRate = 0
            End Try
            Try
                Bosses.Characters(c).DmgInRate = Math.Round(Bosses.Characters(c).CharaDmgIn / Bosses.RaidDmgIn * 100, 2)
            Catch ex As Exception
                Bosses.Characters(c).DmgInRate = 0
            End Try
        Next

        Return True
    End Function

    Private Function GetAttributeNode(ByRef node As Xml.XmlNode, ByVal AttName As String, ByVal AttValue As String) As Xml.XmlElement

        If node.Attributes IsNot Nothing Then
            If node.Attributes(AttName) IsNot Nothing Then
                If node.Attributes(AttName).Value = AttValue Then
                    Return node
                End If
            End If
        End If
        Dim child As Xml.XmlNode
        For Each child In node.ChildNodes
            Dim n As Xml.XmlElement
            n = GetAttributeNode(child, AttName, AttValue)
            If n IsNot Nothing Then
                Return n
            End If
        Next

        Return Nothing
    End Function

    Private Function GetDHtml(ByVal URL As String) As String
        Dim HA As New XmlUtils.AccessHtml
        Dim H2DH As New HTML2XHTMLLib.XHTMLUtilities

        HA.Delay = 100

        Dim html As String = ""
        html = HA.GetHtmlData(URL)

        Dim dhtml As String = ""
        dhtml = H2DH.convertToXHTML(html)

        Return dhtml
    End Function
#End Region

#Region "Estimation"
    Private Function PwsFullAbsorptionCount(ByVal PwsCount As Integer, ByVal RaptureCount As Integer) As Double
        Dim Absorption As Double

        If PwsCount = 0 Then
            Absorption = 0.0
        Else
            Dim rate As Single
            rate = (3.85 * RaptureCount + 120) / (PwsCount + 120)
            If rate > 0.95 Then rate = 0.95

            Absorption = RaptureCount + (PwsCount - RaptureCount) * rate
        End If

        If Absorption < 0.0 Then
            Absorption = 0.0
        ElseIf Absorption > PwsCount Then
            Absorption = PwsCount
        End If

        Return Absorption
    End Function

    Private Sub PwsEstimation(ByRef Raidinfo As RaidData)

        If Raids Is Nothing Then Exit Sub
        Dim r As Integer
        Dim Raid As RaidData = Nothing
        For r = 0 To Raids.Length - 1
            If Raidinfo.BaseUrl = Raids(r).BaseUrl Then
                Raid = Raids(r)
                Exit For
            End If
        Next
        If Raid Is Nothing Then Exit Sub

        Dim heal As Long = 0
        Dim eheal As Long = 0

        Dim b As Integer
        If Raid.Bosses IsNot Nothing Then
            For b = 0 To Raid.Bosses.Length - 1
                Dim boss As BossData = Raid.Bosses(b)
                Dim c As Integer
                Dim cha As CharaData

                If boss.Characters IsNot Nothing Then
                    For c = 0 To boss.Characters.Length - 1
                        cha = boss.Characters(c)

                        Dim h As Integer

                        If cha.Heals IsNot Nothing Then
                            '--- only Priest

                            If cha.CharaClass = "Priest" Then
                                Dim Rapture As Integer = -1
                                Dim GoPWS As Integer
                                Dim Casts As Integer = 0

                                Select Case cha.CharaBuild
                                    Case "Holy"
                                        GoPWS = 5000 / 5
                                    Case "Disc"
                                        GoPWS = 8000 / 5
                                    Case "Shadow"
                                        GoPWS = 3000 / 5
                                    Case Else
                                        GoPWS = 4000 / 5
                                End Select

                                '--- Rapture
                                For h = 0 To cha.Heals.Length - 1
                                    Dim hl As HealData = cha.Heals(h)
                                    '---
                                    If InStr(hl.SpellName, "Rapture") = 1 Then
                                        Rapture = hl.Casts
                                        Exit For
                                    End If
                                Next
                                '--- Glyph of Power Word: Shield
                                For h = 0 To cha.Heals.Length - 1
                                    Dim hl As HealData = cha.Heals(h)
                                    '---
                                    If InStr(hl.SpellName, "Glyph of Power Word: Shield") = 1 Then
                                        GoPWS = hl.AveHit
                                        Exit For
                                    End If
                                Next
                                '--- Power Word: Shield
                                For h = 0 To cha.Heals.Length - 1
                                    Dim hl As HealData = cha.Heals(h)
                                    '---
                                    If InStr(hl.SpellName, "Power Word: Shield") = 1 Then
                                        Casts = hl.Casts

                                        If Casts > 0 Then
                                            If Rapture < 0 Or cha.CharaBuild = "Holy" Then
                                                hl.EffHeal = Math.Round(GoPWS * 5 * 0.65 * Casts, 0)
                                            Else
                                                hl.EffHeal = Math.Round(GoPWS * 5 * PwsFullAbsorptionCount(Casts, Rapture), 0)
                                            End If
                                            hl.Heal = Math.Round(GoPWS * 5 * Casts, 0)

                                            hl.Hits = Casts
                                            hl.AveHit = Math.Round(hl.EffHeal / Casts, 0)
                                        End If
                                        Exit For
                                    End If
                                Next
                            ElseIf cha.CharaClass = "Paladin" Then
                                Dim SacredShield As Integer

                                Select Case cha.CharaBuild
                                    Case "Holy"
                                        SacredShield = 2200 * 5 * 0.88
                                    Case Else
                                        SacredShield = 400 * 5 * 0.7
                                End Select

                                '--- Sacred Shield
                                Dim Casts As Integer
                                For h = 0 To cha.Heals.Length - 1
                                    Dim hl As HealData = cha.Heals(h)
                                    '---
                                    If InStr(hl.SpellName, "Sacred Shield") = 1 Then
                                        Casts = hl.Casts

                                        If Casts > 0 Then
                                            hl.EffHeal = SacredShield * Casts
                                            hl.Heal = SacredShield * Casts

                                            hl.Hits = Casts
                                            hl.AveHit = Math.Round(hl.EffHeal / Casts, 0)
                                        End If

                                        If Casts * 30.0 > cha.CharaPres Then
                                            hl.EffHeal = hl.EffHeal * cha.CharaPres / (Casts * 30.0)
                                        End If

                                        Exit For
                                    End If
                                Next

                            ElseIf cha.CharaClass = "Shaman" Then
                            ElseIf cha.CharaClass = "Druid" Then
                            End If

                            heal = 0
                            eheal = 0

                            '--- healing done
                            For h = 0 To cha.Heals.Length - 1
                                Dim hl As HealData = cha.Heals(h)

                                If InStr(LCase(IgnoreSpells), LCase(hl.SpellName & "@")) = 0 Then
                                    '---
                                    heal += hl.Heal
                                    eheal += hl.EffHeal
                                End If
                            Next

                            If cha.CharaHeal <> heal Or cha.CharaEffHeal <> eheal Then

                                cha.CharaHeal = heal
                                cha.CharaEffHeal = eheal

                                If heal = 0 Then
                                    cha.OverHeal = 0
                                Else
                                    cha.OverHeal = Math.Round(1 - (eheal / heal) * 100, 0)
                                End If
                            End If
                        End If
                    Next

                    '--- raid healing update
                    heal = 0
                    eheal = 0
                    For c = 0 To boss.Characters.Length - 1
                        cha = boss.Characters(c)

                        heal += cha.CharaHeal
                        eheal += cha.CharaEffHeal
                    Next
                    boss.RaidHeal = heal
                    boss.RaidEffHeal = eheal

                    Dim chara2(boss.Characters.Length - 1) As String
                    Dim charaheal(boss.Characters.Length - 1) As Long

                    '--- rate update
                    If boss.RaidEffHeal > 0 Then
                        For c = 0 To boss.Characters.Length - 1
                            cha = boss.Characters(c)
                            cha.EffHealRate = Math.Round(cha.CharaEffHeal / boss.RaidEffHeal * 100, 2)
                        Next
                    End If
                End If
            Next
        End If
    End Sub
#End Region

#Region "Feedback"
    Public Sub FeedbackEstimation(ByRef Raidinfo As RaidData)

        If Raids Is Nothing Then Exit Sub
        Dim r As Integer
        Dim Raid As RaidData = Nothing
        For r = 0 To Raids.Length - 1
            If Raidinfo.BaseUrl = Raids(r).BaseUrl Then
                Raid = Raids(r)
                Exit For
            End If
        Next
        If Raid Is Nothing Then Exit Sub

        Dim b As Integer
        If Raid.Bosses IsNot Nothing Then
            Dim basepath As String = Raid.BaseUrl
            Dim totfilename As String = My.Computer.FileSystem.CombinePath(basepath, "wws-history\data.xml")

            Dim XmlTotDataExist As Boolean = True
            Dim XmlTotData As New Xml.XmlDocument
            Try
                XmlTotData.Load(totfilename)
            Catch ex As Exception
                XmlTotDataExist = False
            End Try

            For b = 0 To Raid.Bosses.Length - 1
                Dim boss As BossData = Raid.Bosses(b)
                Dim c As Integer

                Dim path As String = My.Computer.FileSystem.CombinePath(basepath, boss.Dir)
                Dim filename As String = My.Computer.FileSystem.CombinePath(path, "data.xml")

                Dim XmlDataExist As Boolean = True
                Dim XmlData As New Xml.XmlDocument
                Try
                    XmlData.Load(filename)
                Catch ex As Exception
                    XmlDataExist = False
                End Try

                Dim cha As CharaData
                Dim updated As Boolean = False

                Dim ra As Xml.XmlElement
                For Each ra In XmlData.SelectNodes("raid")
                    ra.Attributes("totheal").Value = boss.RaidHeal
                    ra.Attributes("effheal").Value = boss.RaidEffHeal
                Next

                If boss.Characters IsNot Nothing Then
                    For c = 0 To boss.Characters.Length - 1
                        cha = boss.Characters(c)

                        Dim pl As Xml.XmlElement
                        If XmlDataExist Then
                            For Each pl In XmlData.SelectNodes("raid/player")
                                updated = updated Or updateXml(pl, cha)
                            Next
                        End If

                        Dim tpl As Xml.XmlElement
                        If XmlTotDataExist Then
                            For Each tpl In XmlTotData.SelectNodes("wws-history/raid[@dir=""" & boss.Dir & """]/player")
                                updated = updated Or updateXml(tpl, cha)
                            Next
                        End If
                    Next
                End If
                If updated Then
                    If XmlDataExist Then
                        Try
                            XmlData.Save(filename)
                        Catch ex As Exception
                        End Try
                    End If
                End If
            Next
            If XmlTotDataExist Then
                Try
                    XmlTotData.Save(totfilename)
                Catch ex As Exception
                End Try
            End If
        End If
    End Sub

    Private Function updateXml(ByRef pl As Xml.XmlElement, ByRef cha As CharaData) As Boolean
        Dim updated As Boolean = False

        If pl.GetAttribute("name") = cha.CharaName Then
            '--- only Priest
            'If cha.CharaClass = "Priest" Then
            If pl.Attributes("totheal").Value <> cha.CharaHeal Then
                updated = True
                pl.Attributes("totheal").Value = cha.CharaHeal
            End If
            If pl.Attributes("effheal").Value <> cha.CharaEffHeal Then
                updated = True
                pl.Attributes("effheal").Value = cha.CharaEffHeal
            End If
            If pl.Attributes("ovh").Value <> cha.OverHeal Then
                pl.Attributes("ovh").Value = cha.OverHeal
            End If
            'End If

            If pl.Attributes("heal").Value <> cha.EffHealRate Then
                updated = True
                pl.Attributes("heal").Value = cha.EffHealRate
            End If
        End If

        Return updated
    End Function
#End Region
End Class

